﻿using System;
using spaar.ModLoader;
using UnityEngine;
using Blocks;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Net;
using System.Collections;
using SimpleJSON;
using System.Reflection;
using spaar.ModLoader.UI;

namespace PropellerBlockMod
{


    // If you need documentation about any of these values or the mod loader  
    // in general, take a look at https://spaar.github.io/besiege-modloader. 


    public class PropellerMod : BlockMod

    {

        public override string Name { get; } = "Propeller Block Mod";

        public override string DisplayName { get; } = "Propeller Block Mod";

        public override string Author { get; } = "XultimateX";

        public override Version Version { get; } = Assembly.GetExecutingAssembly().GetName().Version;


        // You don't need to override this, if you leavie it out it will default
        // to an empty string.

        public override string VersionExtra { get; } = "";


        // You don't need to override this, if you leave it out it will default
        // to the current version.

        public override string BesiegeVersion { get; } = "v0.42";


        // You don't need to override this, if you leave it out it will default
        // to false.

        public override bool CanBeUnloaded { get; } = false;


        // You don't need to override this, if you leave it out it will default
        // to false.

        public override bool Preload { get; } = false;


        //桨叶模块 声明
        protected Block PropellerBlock = new Block()       
        #region 桨叶模块 基本属性  

               
            //模块 ID
            
            .ID(600)

            
            //模块 名称
            
            .BlockName("Propeller Block")

            
            //模块 模型信息
            
            .Obj(new System.Collections.Generic.List<Obj>
                        { new Obj(
                                "/PropellerBlockMod/propeller.obj",
                                "/PropellerBlockMod/propeller.png",
                                new VisualOffset(
                                                    new Vector3( 0.75f, 0.75f, 0.64f),
                                                    new Vector3(    0f,    0f, -0.1f),
                                                    new Vector3(-  90f,    0f,  180f)
                                                 )
                              )
                          }
                      )

            
            //模块 图标
            
            .IconOffset(new Icon(
                                        new Vector3(1f, 2f, 0.75f),
                                        new Vector3(-0.2f, -0.2f, 0f),
                                        new Vector3(-20f, 20f, 0f)
                                     )
                            )

            
            //模块 组件
            
            .Components(new Type[] { typeof(PropellerScript), })

                //模块 搜索关键词
                .Properties(new BlockProperties().SearchKeywords(new string[] { "Propeller", "桨" }).Burnable(3))

                //模块 质量
                .Mass(0.5f)

            //模块 是否显示碰撞器
#if DEBUG
            .ShowCollider(true)
#endif
                //模块 碰撞器
                .CompoundCollider(new System.Collections.Generic.List<ColliderComposite>
                                     {
                                    ColliderComposite.Box(
                                                            new Vector3(  0.7f,  0.1f, 2.9f),
                                                            new Vector3(-0.24f,    0f, 1.6f),
                                                            Vector3.zero
                                                          )
                                     }
                                  )

                //模块 载入资源
                /*
                .NeededResources(new System.Collections.Generic.List<NeededResource>
                                    {
                                        new NeededResource(ResourceType.Mesh,"propeller.obj"),
                                        new NeededResource(ResourceType.Texture,"propeller.png")
                                    }
                                )
                */
                //模块 连接点
                .AddingPoints(new System.Collections.Generic.List<AddingPoint>
                                 {
                /*
                                new BasePoint(false,true) //底部连接点。第一个是指你能不能将其他模块安在该模块底部。第二个是指这个点是否是在开局时粘连其他链接点
                                                .Motionable(false,false,false) //底点在X，Y，Z轴上是否是能够活动的。
                                                .SetStickyRadius(0.5f) //粘连距离
                                   */          
                                new AddingPoint(
                                                    new Vector3(  0f,  0f,0.5f), //位置
                                                    new Vector3( 90f,  0f,  0f), //旋转
                                                    true                      //这个点是否是在开局时粘连其他链接点
                                                ).SetStickyRadius(0.15f)      //粘连距离
                                                ,
                                new AddingPoint(
                                                    new Vector3(  0f,  0f, 2.5f), //位置
                                                    new Vector3(-90f,  0f,   0f), //旋转
                                                    true //这个点是否是在开局时粘连其他链接点
                                                ).SetStickyRadius(0.15f) //粘连距离
                }

                             );
        #endregion

        //翼面模块 声明
        protected Block WingPanelBlock = new Block()
        #region 翼面模块 基本属性

                //模块 ID
                .ID(601)

                //模块 名称
                .BlockName("WingPanel Block")

                //模块 模型信息
                .Obj(new System.Collections.Generic.List<Obj>
                        { new Obj(
                                "/PropellerBlockMod/wingpanel.obj",
                                "/PropellerBlockMod/wingpanel.png",
                                new VisualOffset(
                                                    new Vector3(  0.3f, 0.05f,  0.3f),
                                                    new Vector3(    0f,    0f,  0.5f),
                                                    new Vector3(-  90f,    0f,  180f)
                                                 )
                              )
                          }
                      )

                //模块 图标
                .IconOffset(new Icon(
                                        new Vector3(0.3f, 0.1f, 0.3f),
                                        new Vector3(0f, 0f, 0f),
                                        new Vector3(-60f, -10f, 0f)
                                     )
                            )

                //模块 组件
                .Components(new Type[] { typeof(PropellerScript), })

                //模块 搜索关键词
                .Properties(new BlockProperties().SearchKeywords(new string[] { "Wing", "Panel", "翼" }).Burnable(3))

                //模块 质量
                .Mass(0.5f)

            //模块 是否显示碰撞器
#if DEBUG
            .ShowCollider(true)
#endif
                //模块 碰撞器
                .CompoundCollider(new System.Collections.Generic.List<ColliderComposite>
                                     {
                                    ColliderComposite.Box(
                                                            new Vector3(  0.8f,  0.1f, 0.8f),
                                                            new Vector3(    0f,    0f, 0.5f),
                                                            Vector3.zero
                                                          )
                                     }
                                  )

                //模块 载入资源
                /*.NeededResources(new System.Collections.Generic.List<NeededResource>
                                    {
                                        new NeededResource(ResourceType.Mesh,"wingpanel.obj"),
                                        new NeededResource(ResourceType.Texture,"wingpanel.png")
                                    }
                                )
                */
                //模块 连接点
                .AddingPoints(new System.Collections.Generic.List<AddingPoint>
                                 {
                /*
                                new BasePoint(false,true) //底部连接点。第一个是指你能不能将其他模块安在该模块底部。第二个是指这个点是否是在开局时粘连其他链接点
                                                .Motionable(false,false,false) //底点在X，Y，Z轴上是否是能够活动的。
                                                .SetStickyRadius(0.5f) //粘连距离
                                   */          
                                new AddingPoint(
                                                    new Vector3(  0f,  0f,0.5f), //位置
                                                    new Vector3( 90f,  0f,  0f), //旋转
                                                    true                         //这个点是否是在开局时粘连其他链接点
                                                ).SetStickyRadius(0.15f)         //粘连距离
                                                ,
                                new AddingPoint(new Vector3(  0f,   0f, 0.5f), new Vector3(-90f,  0f,   0f), true).SetStickyRadius(0.15f),
                                new AddingPoint(new Vector3(  0f,   0f, 0.5f), new Vector3(  0f,  0f,  90f), true).SetStickyRadius(0.15f),
                                new AddingPoint(new Vector3(  0f,   0f, 0.5f), new Vector3(  0f,  0f, -90f), true).SetStickyRadius(0.15f),
                                new AddingPoint(new Vector3(  0f, 0.4f, 0.5f), new Vector3(  0f,  0f,   0f), true).SetStickyRadius(0.15f),
                                new AddingPoint(new Vector3(  0f,-0.4f, 0.5f), new Vector3(  0f,  0f, 180f), true).SetStickyRadius(0.15f)
                                 }

                             );

        #endregion

        GameObject updater = new GameObject();

        public override void OnLoad()

        {

            // Your initialization code here

            LoadBlock(PropellerBlock);

            LoadBlock(WingPanelBlock);

            updater.AddComponent<Updater>().Url("https://git.oschina.net/XultimateX/GITtest/releases");


        }

        

        public override void OnUnload()

        {

            // Your code here

            // e.g. save configuration, destroy your objects if CanBeUnloaded is true etc

        }




        private void OnKeymapperOpen()

        {
#if DEBUG

            Debug.Log(BlockMapper.CurrentInstance.Block.MapperTypes.Exists(match => match.Key == "propeller"));
#endif

        }


        private void AddControlAxialDrag(BlockBehaviour block)

        {


        }

        }

    //Mod更新检查组件
    public class Updater : MonoBehaviour
    {
        //当前Mod版本号
        private Version CurrentVersion = Assembly.GetExecutingAssembly().GetName().Version;

        //最新Mod版本号
        public Version LatestVersion { get; private set; }

        //最新Mod发布名称
        public string LatestReleaseName { get; private set; }

        //最新Mod发布介绍
        public string LatestReleaseBody { get; private set; }

        //最新Mod发布地址
        public string url { get; set; }

        //更新Mod可用
        public bool UpdaterEnable = false;

        //更新Mod窗口名称
        //public string WindowName { get; set; }

        //最新Mod发布地址网页内容
        private string value;

        //Mod名（码云上的项目名）
        //private string Name;

        private Rect windowDialog = new Rect(300, 300, 320, 150);
        
        private int WindowID = Util.GetWindowID();

        private IEnumerator Start()
        {
            var www = new WWW(url);
            yield return www;
            value = www.text;


            //中间变量
            string str = value;

            //取项目名 确定版本号大致位置（去除主域名 且 在后面加/v）
            string versionKey = url.Substring(url.IndexOf("https://git.oschina.net/") + "https://git.oschina.net/".Length) + "/v";

            //字符位置 确定版本号准确位置（通过项目名长度确定分割字符串起点位置）
            int a = str.IndexOf(versionKey) + versionKey.Length;

            //新版Mod版本号
            LatestVersion = new Version(str.Substring(a, 5));
#if DEBUG
            Debug.Log(LatestVersion + "||" + CurrentVersion);
#endif

            //比较最新版本和当前版本
            if (LatestVersion > CurrentVersion)
            {
#if DEBUG
                Debug.Log(Assembly.GetExecutingAssembly().GetName().Name + "有新版可以更新");
#endif
                //取更新内容标题
                LatestReleaseName = GetData("release-header");

                //取更新内容
                LatestReleaseBody = GetData("markdown-body");
                
                //更新可用为真
                UpdaterEnable = true;
            }
            else
            {
#if DEBUG
                Debug.Log(Assembly.GetExecutingAssembly().GetName().Name + "无需更新");
#endif
            }

        }

        public void Url(string str)
        {
            url = str;
        }

        //获取相关信息
        private string GetData(string key)
        {
            key = "'" + key + "'>";
            int a = value.IndexOf(key);
            string str = value.Remove(0, a + key.Length);

            a = str.IndexOf(">");
            str = str.Remove(0, a + 1);

            a = str.IndexOf("<");
            str = str.Substring(0, a).Replace("&#x000A;", "\n");
#if DEBUG
            Debug.Log(str);
#endif
            return str;
        }

        private void OnGUI()
        {
            if (!UpdaterEnable) return;

            GUI.skin = ModGUI.Skin;
            GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f, 0.7f);

            windowDialog = GUI.Window(WindowID, windowDialog, doWindow, Assembly.GetExecutingAssembly().GetName().Name + " 更新提示");

        }

        private void doWindow(int windowId)
        {
            //画新版资料
            //GUILayout.Label("有新版本可以更新", new GUIStyle(Elements.Labels.Default) { alignment = TextAnchor.MiddleCenter,fontSize = 12 });    
            
            GUILayout.Label($"<b>v{LatestVersion}: {LatestReleaseName}</b>",new GUIStyle(Elements.Labels.Default) { alignment = TextAnchor.MiddleCenter, fontSize = 15 });

            GUILayout.Label(LatestReleaseBody,new GUIStyle(Elements.Labels.Default) { fontSize = 12, margin = new RectOffset(8, 8, 16, 16) });

            //画更新按钮
            if (GUILayout.Button("去更新页面下载新版", Elements.Buttons.ComponentField))
            {
                Application.OpenURL(url);
            }

            //画关闭按钮
            if (GUI.Button(new Rect(windowDialog.width - 38, 8, 30, 30), "×", Elements.Buttons.Disabled))
            {
                Destroy(this);
                Debug.Log("拒绝更新无可救药...");
            }

            //使窗口能够拖拽
            GUI.DragWindow();

            windowDialog.height = 134f + LatestReleaseBody.Split('\n').Length * 16f;
        }
    }

    public class ControlAxialDrag : MonoBehaviour

    {
        //声明 要加入控制升力功能的零件编号

        private List<int> BlockID = new List<int> { 25, 26, 34, 55, 600, 601 };


        private void Start()
            {
#if DEBUG
                Debug.Log("Start form control axial drag");
#endif
            }


        private void Update()
            {
#if DEBUG
                if (Input.GetKeyDown(KeyCode.C))
                    Debug.Log("input C form control axial drag Update");

#endif
                if (Input.GetKeyDown(KeyCode.Mouse0) && !StatMaster.isSimulating && BlockMapper.CurrentInstance.enabled)
                {
                    Debug.Log("点击左键 在建造模式下 ");
                    foreach (var id in BlockID)
                    {
                        if (id == BlockMapper.CurrentInstance.Block.GetBlockID())
                            Debug.Log("选择的是气动零件");
                    }

                }

            }


    }


    public class PropellerScript : BlockScript  //模块 脚本

    {

#region 功能变量

            //声明 功能 按键
            protected MKey Key;

            //声明 初始生效模式 按钮
            protected MToggle InitialEffect;

            //声明 按住生效模式 按钮
            protected MToggle ToggleMode;

            //声明 气动模式 按钮
            protected MToggle WindMode;

            //声明 质量 滑条
            protected MSlider Mass;

            //声明 生效模式 旗帜
            protected bool Effect;

#endregion

#region 计算变量-系统气动

            //声明 各轴 拉力系数
            public Vector3 axisDrag = new Vector3(0f, 0.02f, 0f);

            //声明 速度 当前大小平方
            public float currentVelocitySqrMagnitude;

            //声明 拖拽 量
            public float dragAmount;

            //声明 拖拽 拉力大小
            public float dragForceMagnitude;

            //声明 拖拽 拉力方向
            public Vector3 dragForceVector;

            //声明 速度平方 最大值
            public float velocitySqrCap = 900f;

#endregion

#region 计算变量-自定气动

            //声明 空气 密度
            protected float AirDensity = 1f;

            //声明 桨叶 面积
            protected float PropellerArea = 3f;

            //声明 桨叶 投影面积
            protected float PropellerProjectArea;

            //声明 桨叶 速度
            protected Vector3 PropellerVelocity;

            //声明 桨叶 姿态
            protected Transform PropellerAttitude;

            //声明 桨叶 攻角
            protected float PropellerAttackAngle;

            //声明 升力 系数
            protected float LiftCoefficient;

            //声明 阻力 系数
            protected float ResistanceCoefficient;

            //声明 最大值
            protected float ForceCap = 4000f;
#endregion


#if DEBUG
            private GameObject Mark;
            private GameObject angle_mark;
            private GameObject lift_mark;
            private string lift_test = "";
            private string resistance_test = "";
            private string angle_test = "";
            private string area_test = "";
            private string rc_test = "";
            private string lc_test = "";
#endif

            public override void SafeAwake()
            {
                base.SafeAwake();

                //添加 功能按键 参数
                Key = AddKey("开关键", "Switch", KeyCode.P);

                //添加 模式切换按钮 参数
                InitialEffect = AddToggle("初始生效", "Effect", true);

                //添加 模式切换按钮 参数
                ToggleMode = AddToggle("按住生效", "State", false);

                //添加 气动切换按钮 参数
                WindMode = AddToggle("默认气动", "Wind", true);

                //添加 质量滑条 参数
                Mass = AddSlider("质量", "Mass", 0.5f, 0.2f, 2f);

                //委托 质量改变 事件
                Mass.ValueChanged += new ValueChangeHandler(mass_ValueChanged);


            }

            //改变 质量 事件
            public void mass_ValueChanged(float Value)
            {
                this.Rigidbody.mass = Value;
            }

            protected virtual System.Collections.IEnumerator UpdateMapper()
            {
                if (BlockMapper.CurrentInstance == null)
                    yield break;
                while (Input.GetMouseButton(0))
                    yield return null;
                BlockMapper.CurrentInstance.Copy();
                BlockMapper.CurrentInstance.Paste();
                yield break;
            }

            public override void OnSave(XDataHolder stream)
            {
                base.OnSave(stream);
                SaveMapperValues(stream);
            }

            public override void OnLoad(XDataHolder stream)
            {
                base.OnLoad(stream);
                LoadMapperValues(stream);
            }

            protected override void BuildingUpdate()
            {
                base.BuildingUpdate();
                if (this.GetBlockID() == 600)
                {
                    Rigidbody.centerOfMass = new Vector3(-0.1f * transform.localScale.x, 0, 1.5f * transform.localScale.z);
                }
                mass_ValueChanged(Mass.Value);
            }

            protected override void OnSimulateFixedStart()
            {
                base.OnSimulateFixedStart();
                //连接点 破坏力 和 破坏力矩 为无穷大
                ConfigurableJoint conf = this.GetComponent<ConfigurableJoint>();
                conf.breakForce = Mathf.Infinity;
                conf.breakTorque = Mathf.Infinity;
            }

            protected override void OnSimulateFixedUpdate()
            {
                base.OnSimulateFixedUpdate();
                PropellerVelocity = this.rigidbody.velocity;
                PropellerAttitude = this.rigidbody.transform;

#if DEBUG
                //Mark.transform.position = PropellerAttitude.InverseTransformDirection(PropellerVelocity) + this.transform.position ;      

#endif

                if (Effect && WindMode.IsActive == false)
                {

                    //获取桨叶在速度方向的攻角
                    PropellerAttackAngle = Attack_Angle(PropellerAttitude, PropellerVelocity);

                    //获取桨叶在速度方向的面积
                    PropellerProjectArea = Project_Area(PropellerAttackAngle, PropellerArea);



                    //this.rigidbody.AddRelativeForce(Force(PropellerAttitude,PropellerVelocity,PropellerArea));

                    //计算桨叶上的力  从自身坐标转换到世界坐标
                    Vector3 force = transform.TransformDirection(Force(PropellerAttitude, PropellerVelocity, PropellerArea));

                    //计算添加力的位置  先转换到自身坐标，平移后再转换到世界坐标

                    if (GetBlockID() == 600)
                    {
                        Vector3 position = transform.TransformDirection(transform.InverseTransformDirection(transform.position) + new Vector3(-0.35f * transform.localScale.x, 0, 1.5f * transform.localScale.z));
#if DEBUG
                        lift_mark.transform.position = force.normalized * 3 + position;
#endif
                        //在位置上添加力
                        rigidbody.AddForceAtPosition(force, position);
                    }
                    else if (GetBlockID() == 601)
                    {
#if DEBUG
                        lift_mark.transform.position = force.normalized * 3 + transform.position;
#endif
                        //在位置上添加力
                        rigidbody.AddForce(force);
                    }



                }
                if (Effect && WindMode.IsActive)
                {
#if DEBUG
                    lift_mark.transform.position = transform.TransformDirection(Force(PropellerAttitude, PropellerVelocity)).normalized * 3 + transform.position;
#endif
                    this.rigidbody.AddRelativeForce(Force(PropellerAttitude, PropellerVelocity));
                }
            }

            protected override void OnSimulateStart()
            {

                base.OnSimulateStart();

                //判断 初始生效模式
                Effect = InitialEffect.IsActive ? true : false;

                //判断 初始气动模式
                this.rigidbody.drag = 0;
                if (Effect && WindMode.IsActive)
                {
                    this.rigidbody.angularDrag = 0.05f;
                }
                else if (Effect && !WindMode.IsActive)
                {
                    this.rigidbody.angularDrag = 0;
                }
#if DEBUG
                Mark = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                Destroy(Mark.GetComponent<SphereCollider>());

                angle_mark = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                Destroy(angle_mark.GetComponent<SphereCollider>());

                lift_mark = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                Destroy(lift_mark.GetComponent<SphereCollider>());
#endif

            }

            protected override void OnSimulateUpdate()
            {
                base.OnSimulateUpdate();

                if (Key.IsPressed || (Key.IsReleased && ToggleMode.IsActive))
                {
                    Effect = !Effect;
#if DEBUG
                    Debug.Log("初始生效 " + Effect);
#endif
                }

            }
#if DEBUG
            protected override void OnSimulateExit()
            {
                base.OnSimulateExit();
                Destroy(Mark);
                Destroy(angle_mark);
                Destroy(lift_mark);
            
            }


            void OnGUI()
            {

                GUI.Label(new Rect(360, 360, 200, 50), angle_test + "|" + area_test + "|" + lc_test + "|" + rc_test);
                GUI.Label(new Rect(360, 410, 100, 50), lift_test + "|" + resistance_test + "||" + transform.localScale.ToString());

            }
#endif
            //力的计算 默认模式
            protected Vector3 Force(Transform attitude, Vector3 velocity)
            {

                //变换方向从世界坐标到自身坐标
                velocity = attitude.InverseTransformDirection(velocity);
                //Mark.transform.position = this.Rigidbody.velocity.normalized + this.transform.position ;
                //判断是否在风里
                if (this.InWind)
                {
                    //获取风力
                    Vector3 wind = attitude.InverseTransformDirection(this.CurrentWindController.windPower * 2f);

                    velocity.x = (axisDrag.x == (float)0 || Math.Abs(velocity.x) < Math.Abs(wind.x) ? 0f : velocity.x - wind.x);
                    velocity.y = (axisDrag.y == (float)0 || Math.Abs(velocity.y) < Math.Abs(wind.y) ? 0f : velocity.y - wind.y);
                    velocity.z = (axisDrag.z == (float)0 || Math.Abs(velocity.z) < Math.Abs(wind.z) ? 0f : velocity.z - wind.z);

                    dragForceVector = Vector3.Scale(-velocity, axisDrag * 5f);
                    currentVelocitySqrMagnitude = Math.Min(velocity.sqrMagnitude, velocitySqrCap);
                    return dragForceVector * currentVelocitySqrMagnitude;

                }
                else
                {

                    dragForceVector = Vector3.Scale(-velocity, axisDrag);
                    //Mark.transform.position = dragForceVector.normalized + this.transform.position;
                    currentVelocitySqrMagnitude = Mathf.Min(velocity.sqrMagnitude, velocitySqrCap);
                    return dragForceVector * currentVelocitySqrMagnitude;

                }
            }


            //攻角计算 桨叶相对桨叶速度的攻角
            protected float Attack_Angle(Transform attitude, Vector3 velocity)
            {
                float angle = Vector3.Angle(velocity, attitude.up);
#if DEBUG
                angle_test = angle.ToString("#0.0");
#endif
                return angle;
            }

            //面积计算 运动方向的桨叶投影面积
            protected float Project_Area(float angle, float area)
            {
                float value = Mathf.Abs(Mathf.Cos(angle * Mathf.Deg2Rad)) * area;
#if DEBUG
                area_test = value.ToString("#0.0");
#endif
                return value;

            }

            //阻力系数计算 阻力系数与攻角有关
            protected float Resistance_Coefficient(float angle)
            {
                //阻力系数方程：y = 1.5^(x/10) /38
                float coefficient;
                //攻角数据处理
                angle = Mathf.Clamp(Mathf.Abs(90 - angle), 0, 90);

                //根据攻角计算阻力系数
                coefficient = Mathf.Pow(1.5f, angle / 10f) / 38;

                //保留一位小数
                coefficient = float.Parse(coefficient.ToString("#0.0"));
#if DEBUG
                rc_test = coefficient.ToString();
#endif
                return coefficient;

            }

            //升力系数计算 升力系数与攻角有关
            protected float Lift_Coefficient(float angle)
            {

                //升力系数方程：y = -1/900x^2 + 1/15x(0-45度)  y = 65/x - 0.72(45-90度)
                float coefficient;
                //攻角数据处理
                angle = Mathf.Clamp(Mathf.Abs(90 - angle), 0, 90);

                //根据攻角计算升力系数
                if (angle > 45)
                {
                    coefficient = 65f / angle - 0.72f;
                }
                else
                {
                    coefficient = -1f / 900f * Mathf.Pow(angle, 2f) + 1f / 15f * angle;
                }

                //保留一位小数
                coefficient = float.Parse(coefficient.ToString("#0.0"));
#if DEBUG
                lc_test = coefficient.ToString();
#endif
                return coefficient;
            }

            //力的大小 
            protected float Force_Magnitude(float coefficient, float airDensity, float speed, float area)
            {
                //方程：Fm = 1/2 * 力系数 * 空气密度 * 速度平方 * 有效面积 
                float Fm = 1f / 2f * coefficient * airDensity * Mathf.Pow(speed, 2) * area;

                return Fm;
            }

            //力的计算 自定模式
            protected Vector3 Force(Transform attitude, Vector3 velocity, float area)
            {

                //所需参数计算 攻角 有效面积 阻力升力系数 相对速度
                float aa = Attack_Angle(attitude, velocity);
                float pa = Project_Area(aa, area);
                float rc = Resistance_Coefficient(aa);
                float lc = Lift_Coefficient(aa);
                float rv = velocity.magnitude;

                Vector3 forceVector = attitude.transform.InverseTransformDirection(velocity).normalized;

                //自定阻力计算
                float resistance = Mathf.Min(Force_Magnitude(rc, AirDensity, rv, area) * 0.12f, ForceCap);

                //自定升力计算
                float lift = Mathf.Min(Force_Magnitude(lc, AirDensity, rv, area), ForceCap);
#if DEBUG
                resistance_test = resistance.ToString("#0.0");
                lift_test = lift.ToString("#0.0");
#endif
                forceVector = forceVector * -resistance + Vector3.Scale(-forceVector, new Vector3(resistance - 1, lift, 0));

                return forceVector;
            }

        } //模块 脚本

    }

